<Html>
  <head>
    <title>CSS语法</title>
  </head>
  <body>
    <script>
      /*
          页面样式与布局

                      uni-app 有 vue页面、nvue 页面、uvue页面。

                      ①、 vue 页面时 webview 渲染的的

                      ②、app-nvue 页面时原生渲染的，其样式比web会限制更多，另见 nvue 的 css。 https://zh.uniapp.dcloud.io/tutorial/nvue-css.html

                      ③、app-uvue 页面是原生渲染的，是 web 的 css 子集，另见 uvue 的css。 https://doc.dcloud.net.cn/uni-app-x/css/

                uni-app 的css与 web 的css基本一致。
                
                本文没有讲解 css的用法。在你了解web css的基础上，本文本讲述一些样式相关注意事项。

                本文重点介绍 vue 页面， 也就是 webview 中的样式注意事项。

      */


      /*
          一、css 预处理器支持

                    uni-app支持 less、sass、scss 、stylus 等预处理器。

                    参考 ： css 预处理器 https://developer.mozilla.org/zh-CN/docs/Glossary/CSS_preprocessor


                    ★、vue2开发者 sass 预处理注意：

                          sass的预处理器，早年使用 node-sass,也就是vue2 最初默认的编译器。

                          sass 官方推出了 dart-sass来替代。  node-sass已经停止维护很久了。

                          vue3默认使用的是 dart-sass.

                          另外 node-sass 不支持arm cpu，也即Apple的M系列CPU，导致HBuilderX的 arm版只能使用 dart-sass.

                          node-sass 有些淘汰的学法，在dart-sass里已不再支持。

                          所以开发者在从vue2升vue3时，使用HBuilderX arm版时，会发现老的vue2项目如果写了废弃scss语法，会编译报错。

                          这种分裂也导致插件生态混乱，导致多人协作时，比如一个项目有人用arm专版，有人使用intel版，造成协作障碍。

                          DCloud推荐开发者尽快升级到vue3，改用dart-sass。

                          从 HBuilderX 4.56+ ，vue2 项目也将默认使用 dart-sass 预编译器。


                    注意：

                        ①、如果您希望继续使用node-sass，可以在manifest.json根节点配置: "sassImplementationName": "node-sass"; 可选值 "dart-sass" | "node-sass"。

                        ②、sassImplementationName 配置仅限 uni-app（vue2）项目且非 HBuilderX Mac Arm 版本，HBuilder Mac Arm 版本以及uni-app vue3和uni-app x项目仅支持dart-sass。

                    node-sass升级dart-sass常见问题及改进方法：

                        ①、SassError: expected selector. /deep/

                              解决方案：/deep/ 替换成::v-deep

                        ②、WARNING: Using / for division is deprecated and will be removed in Dart Sass 2.0.0.

                              解决方案：使用 math.div() 替换除法运算符 详情，如果遇到@use 'sass:math';编译报错，可以在uni.scss中定义，详情

                        ③、SassError: xxx and xxx are incompatible.

                               解决方案：calc 在特定情况需要带单位，比如：width: calc(100% - 215) 修改为：width: calc(100% - 215px)

      */

      /*
          二、尺寸单位

               1、 uni-app 支持的通用 css 单位包括 px、rpx

                      ①、px 即屏幕像素

                      ②、rpx 即响应式 px，一种根据屏幕宽度自适应的动态单位。

                                以 750 宽的屏幕为基准，750rpx 恰好为屏幕宽度。
                                
                                屏幕变宽，rpx 实际显示效果会等比放大，
                                
                                但在 App（vue2 不含 nvue） 端和 H5（vue2） 端屏幕宽度达到 960px 时，默认将按照 375px 的屏幕宽度进行计算，具体配置参考：rpx 计算配置 。

               2、vue 页面支持下面这些普通H5单位，但在 nvue 里不支持。

                       ①、rem 根字体大小可以通过 page-meta 配置抖音小程序和飞书小程序：  

                                屏幕宽度/20、百度小程序：16px、支付宝小程序：50px

                       ②、vh  Viewpoint height ,视窗高度， 1vh 等于视窗高度的1%

                       ③、vw  viewpoint width, 视窗宽度， 1vw 等于视窗宽度的1%

               nvue 还不支持百分比单位。

               App 端，在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位，只支持 px。注意此时不支持 rpx

               nvue 中， uni-app 模式 可以使用 px、rpx， 表现与 vue 中基本一致，另外启用 dynamicRpx 后可以适配屏幕大小变化而变化。

               weex模式目前遵循 weex的单位，它的单位比较特殊：

                      ①、px：， 以750宽的屏幕为基准动态计算的长度单位，与 vue页面中的 rpx 立减相同。
                               (一定要注意 weex 模式的px，和vue里的px逻辑不一样)

                      ②、wx：  与设备屏幕宽度无关的长度单位，与 vue 页面中的 px 理念相同。

                 

                3、rpx的详细说明

                      设计师在提供设计图时，一般只提供一个分辨率的图。

                      严格按设计图标注的px做px做开发，在不同宽度的手机上界面很容易变形。

                      而且主要是宽度变形。高度一般因为有滚动条，不容易出问题。

                      由此，引发了较强的动态宽度单位需求。

                      微信小程序设计了 rpx 来解决这个问题。 
                      
                      uni-app 在 App 端、H5端都支持了 rpx,并且可以配置不同屏幕宽度的计算方式，具体参考： rpx计算配置。

                      rpx 是相对于基准宽度单位，可以根据屏幕宽度进行自适应。  uni-app规定屏幕的基准宽度为 750 rpx。
                      
                      开发者可以通过设计稿基准宽度计算页面rpx值，设计稿 1px  与框架样式1rpx转换公式如下：

                                  "设计稿 1px / 设计稿基准宽度 = 框架样式 1rpx /750rpx"

                      换言之，页面元素宽度在 uni-app 中的宽度计算公式：

                                   "750 * 元素在设计稿中的宽度 / 设计稿基准宽度"

                      注意：

                          ①、注意 rpx 是和宽度相关的单位，屏幕越宽，该值实际像素越大。
                             如不想根据屏幕宽度缩放，则应该使用 px 单位。

                          ②、如果开发者在字体或高度中也使用了 rpx ，那么需注意这样的写法意味着随着屏幕变宽，
                             字体会变大、高度会变大。如果你需要固定高度，则应该使用 px 。

                          ③、rpx 不支持动态横竖屏切换计算，使用 rpx 建议锁定屏幕方向

                          ④、设计师可以用 iPhone6 作为视觉稿的标准。

                          ⑤、如果设计稿不是 750px，HBuilderX 提供了自动换算的工具，详见：HBuilderX中自动转换px为upx。

                          ⑥、App 端，在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位，只支持 px，不支持 rpx

                          ⑦、早期 uni-app 提供了 upx ，目前已经推荐统一改为 rpx 了，详见
      */
    


      /*
          三、样式导入

                    使用@import语句可以导入外联样式表，@import后跟需要导入的外联样式表的相对路径，用;表示语句结束。

                    eg:

                             <style>
                                  @import "../../common/uni.css";

                                  .uni-card {
                                      box-shadow: none;
                                  }
                              </style>
      */

      /*
          四、内联样式

                      框架组件上支持使用 style、Class属性来控制组件的样式。

                      1、style:  静态的样式同意写到class中。 style接收动态的样式，在运行时会进行解析，
                       
                                 请尽量避免将静态的样式写进 style中，以免影响渲染速度。

                                <view :style="{color:color}" />  // 尽量在 style 中绑定动态样式
                                
                      2、class： 用于直接顶样式规则，其属性值是样式规则中类选择器名(样式类名)称的集合，样式类名不需要带上，
                                 样式类名之间用空格分隔。

                                 <view class="normal_view"/>

      */

      /*
          五、选择器

                          目前支持的选择器有：

                          选择器                  样例                   样例描述

                          .class                  .intro                选择所有拥有 class="intro"的组件

                          #id                    #firstname             选择拥有id="firstname"的组件

                          element                 view                  选择所有 view 组件

                          element,element        view,checkbox          选择所有文档的View组件或所有的 checkbox 组件

                          ::after                view::after            在view组件后边插入内容，仅vue页面生效

                          ::before               view::before           在 view 组件前面掺入内容，仅 vue 页面生效

                  注意：

                        ①、在 uni-app 中不能使用 * 选择器

                        ②、微信小程序自定义组件中仅支持 class 选择器

                        ③、page 相当于 body 节点，例如：

                              <!-- 设置页面背景颜色，使用 scoped 会导致失效 -- >
                              page {
                                background-color: #ccc;
                              }

                        ④、web端可以使用html 、body、：root 等选择器。 
                        
                                 由于页面的 css 样式隔离，且 html节点并未添加 data-xxx属性，

                                 html、:root 写在页面 style 内无效，只能写在App.vue 内。
      */

      /*
          六、全局样式与局部样式

                      定义在App.vue 中的样式为全局样式，作用于每一个页面。

                      在 pages 目录下的 vue 文件中定义的样式为局部样式，只作用在对应的页面，并会覆盖 App.vue 中相同的选择器。


                      注意：

                            ①、App.vue  中通过 @import 语句可以带入外联样式，一样作用于每一个页面。

                            ②、nvue 页面暂不支持全局样式
      */


      /*
          七、CSS变量

                    uni-app 提供嫩枝CSS变量

                    css 变量                描述                 App                小程序      H5

                    --status--bar-height    系统状态栏搞对       系统状态栏高度、     25px        0
                                                                nvue 注意见下

                    --window-top         内容区域距离顶部的距离   0                   0          NavigationBar的高度

                    --window-bottpm      内部区域距离底部的距离   0                   0          TabBar的高度



                  注意：  

                        ①、var(--status-bar-height) 此变量在微信小程序环境为固定 25px ，在App里为手机时机状态栏高度。

                        ②、当设置 "navigationStyle":"custom"取消原生导航栏后，由于窗体为沉浸式，占据了状态栏位置。

                           此时可以使用一个高度为 var(--status-bar-height)的 view 放在页面顶部，避免页面内容出现在状态栏。

                        ③、由于在H5端，不存在原生导航栏和 tabbar , 也是前端 div 模拟。如果设置了一个固定位置为居底 view,

                           在小程序和App端时在 tabbar 上方，但 H5 端会与 tabbar 重叠。

                           此时可使用  --window-bottom ,不管在哪个端，都是固定在tabbar上方。

                        ④、目前nvue 在App端，还不支持 --status-bar-height变量，
                        
                           替代方案是在页面 onLoad时通过 uni.getSystemInfoSync().statusBarHeight获取状态栏高度，

                           然后通过 style 绑定方式给站位 view设定高度。

                           下方提供了实例代码：

                    ★、代码块

                           快速书写 css 变量的方法是：在 css 中敲 hei，在候选助手中即可看到 3 个 css 变量。（HBuilderX 1.9.6 以上支持）


                           ①、普通页面使用css变量：

                                  <template>
                                    //  HBuilderX 2.6.3+ 新增 page-meta, 详情：https://uniapp.dcloud.io/component/page-meta
                                    <page-meta>
                                      <navigation-bar />
                                    </page-meta>
                                    <view>
                                      <view class="status_bar">
                                        // 这里是状态栏 
                                      </view>
                                      <view>状态栏下的文字</view>
                                    </view>
                                  </template>
                                  <style>
                                    .status_bar {
                                      height: var(--status-bar-height);
                                      width: 100%;
                                    }
                                  </style>



                                  <template>
                                    <view>
                                      <view class="toTop">
                                        // 这里可以放一个向上箭头，它距离底部tabbar上浮10px
                                      </view>
                                    </view>
                                  </template>
                                  <style>
                                    .toTop {
                                      bottom: calc(var(--window-bottom) + 10px);
                                    }
                                  </style>


                            ②、nvue页面获取状态栏高度

                                  <template>
                                    <view class="content">
                                      <view :style="{ height: iStatusBarHeight + 'px'}"></view>
                                    </view>
                                  </template>

                                  <、script>
                                    export default {
                                      data() {
                                        return {
                                          iStatusBarHeight: 0,
                                        };
                                      },
                                      onLoad() {
                                        this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight;
                                      },
                                    };
                                  </、script>
        */

        /*
            八、固定值

                     uni-app 中以下组件的高度是固定的，不可修改：
                     
                     
                     组件                描述                   App                        H5

                     NavigationBar      导航栏                  44px                      44px

                     TabBar             底部选项卡              HBuilderX 2.3.4           50px
                          
                     
                     
                    各小程序平台，包括同小程序平台的ios 和 Android的高度也不一样。
        */

        /*
              九、Flex布局

                      为了支持跨平台，框架建议使用Flex布局，关于Flex布局可以参考外部文档 ：

                      https://css-tricks.com/snippets/css/a-guide-to-flexbox/

                      http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
        */


        /*
              十、背景图片

                      uni-app 支持使用在css里设置背景图片，使用方式与普通 web 项目答题相同，但需要注意以下几点：

                            ①、支持 base64格式图片

                            ②、支持网络路径图片

                            ③、小程序不支持在css中使用本地文件，包括本地的背景图和字体文件。需要以 base64方式方可使用。

                            ④、使用本地路径背景图片需注意：

                                   为方便开发者，在背景图片小于 40kb 时，uni-app 编译到不支持本地背景图的平台时，会自动将其转化为 base64 格式；

                                   图片大于等于 40kb，会有性能问题，不建议使用太大的背景图，如开发者必须使用，
                                   则需自己将其转换为 base64 格式使用，或将其挪到服务器上，从网络地址引用。

                                   本地背景图片的引用路径推荐使用以 ~@ 开头的绝对路径。

                                   .test2 {
                                      background-image: url('~@/static/logo.png');
                                    }

                    注意：  微信小程序不支持相对路径 (真机不支持，开发工具支持)

        */

        /*
              十一、字体图标

                       uni-app 支持使用字体图标，使用方式与普通web项目相同，需要注意以下几点：

                       ①、支持 base64格式字体图标。

                       ②、支持网络路径字体图标

                       ③、小程序不支持在css 中使用本地文件，包括本地的背景图片和字体文件。需以base64方式可使用。

                       ④、网络路径必须加协议头 https

                       ⑤、从 http://www.iconfont.cn 上拷贝的代码，默认是没加协议头的

                       ⑥、从 http://www.iconfont.cn 上下载的字体文件，都是同名字体（字体名都叫 iconfont，安装字体文件时可以看到），
                          
                          在 nvue 内使用时需要注意，此字体名重复可能会显示不正常，可以使用工具修改。

                       ⑦、使用本地路径图标字体需注意：

                                  为方便开发者，在字体文件小于 40kb 时，uni-app 会自动将其转化为 base64 格式；

                                  字体文件大于等于 40kb，仍转换为 base64 方式使用的话可能有性能问题，如开发者必须使用，则需自己将其转换为 base64 格式使用，或将其挪到服务器上，从网络地址引用；

                                  字体文件的引用路径推荐使用以 ~@ 开头的绝对路径。

                                      @font-face {
                                        font-family: test1-icon;
                                        src: url('~@/static/iconfont.ttf');
                                      }
                      nvue中不可直接使用 css 的方式引入字体文件，需要使用以下方式在 js 内引入。
                      
                      nvue 内不支持本地路径引入字体，请使用网络链接或者base64形式。src字段的url的括号内一定要使用单引号

                                  var domModule = weex.requireModule('dom');
                                  domModule.addRule('fontFace', {
                                    fontFamily: 'fontFamilyName',
                                    src: "url('https://...')",
                                  });

                                  <template>
                                    <view>
                                      <view>
                                        <text class="test">&#xe600;</text>
                                        <text class="test">&#xe687;</text>
                                        <text class="test">&#xe60b;</text>
                                      </view>
                                    </view>
                                  </template>
                                  <style>
                                    @font-face {
                                      font-family: 'iconfont';
                                      src: url('https://at.alicdn.com/t/font_865816_17gjspmmrkti.ttf') format('truetype');
                                    }
                                    .test {
                                      font-family: iconfont;
                                      margin-left: 20rpx;
                                    }
                                  </style>
        */


    </script>
  </body>
</Html>